package org.thanos.iot.service.login;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.thanos.iot.controller.login.LoginVo;
import org.thanos.iot.entity.user.SysUser;
import org.thanos.iot.entity.user.SysUserRole;
import org.thanos.iot.dao.role.SysRoleMenuMapper;
import org.thanos.iot.dao.user.SysUserDao;
import org.thanos.iot.dao.user.SysUserRoleDao;
import org.thanos.iot.service.menu.MenuService;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Service("loginService")
public class LoginServiceImpl implements LoginService {

    @Value("${shiro.session.timeout}")
    private Integer timeout;

    @Autowired
    private SysUserDao userMapper;

    @Autowired
    private SysUserRoleDao userRoleMapper;

    @Autowired
    private SysRoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuService menuService;

    @Override
    public LoginVo login(String loginId, String password) {
        Assert.isTrue(StringUtils.isNotBlank(loginId), "loginId must not be null");
        Assert.isTrue(StringUtils.isNotBlank(password), "password must not be null");
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(loginId, password);
        subject.login(token);
        LoginVo loginVo = new LoginVo();
        SysUser iotUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Session session = SecurityUtils.getSubject().getSession();
        loginVo.setToken(String.valueOf(session.getId()));
        loginVo.setTokenPeriod(Timestamp.valueOf(LocalDateTime.now().plusSeconds(timeout)).getTime());
        SysUserRole role = userRoleMapper.selectByUserId(iotUser.getId());
        if (Objects.nonNull(role)) {
            List<Integer> menuIds = roleMenuMapper.queryByRoleId(role.getRoleId());
            if (CollectionUtils.isNotEmpty(menuIds)) {
                loginVo.setMenus(menuService.queryByMenuIds(menuIds));
            }
        }
        return loginVo;
    }

    @Override
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }
}
